Release 10.1A: OpenEdge Development:
Progress 4GL Reference


FUNCTION statement

Defines or forward declares a user-defined function.

You can also use the FUNCTION statement to invoke a Web service operation. For more information on invoking Web service operations, see OpenEdge Development: Web Services .

Syntax

FUNCTION function-name [ RETURNS ] data-type [ PRIVATE ]
  [ ( parameter [, parameter ] ... ) ]
  {     FORWARD 
     |  [ MAP [ TO ] actual-name ] IN proc-handle
     |  IN SUPER
  } 

Use the following syntax to invoke a Web service operation:

FUNCTION operationName [ RETURNS ] data-type  
  [ ( parameter [ , parameter ] ... ) ] 
  IN hPortType . 

function-name

The name of the function. You must avoid Progress reserved keywords. For a list of Progress keywords, see the Keyword Index in this manual.

[ RETURNS ] data-type

Indicates the function returns a value, and specifies the data type of that return value. Progress provides the following return value data types: CHARACTER, CLASS, COM-HANDLE, DATE, DATETIME, DATETIME-TZ, DECIMAL, HANDLE, INTEGER, LOGICAL, LONGCHAR, MEMPTR, RAW, RECID, ROWID, and WIDGET-HANDLE.

You specify a class or interface as a return value for a user-defined function using the following syntax:

[ CLASS ] { type-name }  

Progress passes the object reference associated with the class or interface (by value), not the class or interface itself.

type-name

A character string that specifies the type name of the class or interface. Specify a type name using the package.class-name syntax as described in the Type-name syntax reference entry in this book.

If the specified class or interface type name conflicts with an abbreviation of a built-in Progress data type name, such as INT for INTEGER, you must specify the CLASS keyword.

Note: If you invoke a function on an AppServer, the function cannot return a value as a LONGCHAR, MEMPTR, or CLASS.

PRIVATE

Indicates the following about the user-defined function:

( parameter [, parameter ] ... )

Defines one or more parameters of the function.

For the parameter definition syntax, see the Parameter definition syntax reference entry in this book.

FORWARD

Lets a procedure reference a user-defined function whose definition has not yet appeared. You must use this option when the definition of the function appears later in the procedure.

The FUNCTION statement with the FORWARD option must include the following information on the function: the data type it returns, and the data type and mode (INPUT, OUTPUT, or INPUT-OUTPUT) of each parameter.

This entry uses the term forward declaration to refer to statements such as the FUNCTION statement with the FORWARD option. This entry also mentions forward declaring user-defined functions.

If you forward declare a user-defined function, reference it, and do not define it before the end of the procedure, the compiler reports an error.

IN proc-handle

Indicates that the function’s definition resides in another procedure. The proc-handle parameter represents an expression that evaluates to a handle to the procedure that defines the function. This procedure can be an active procedure in the local context or a remote persistent procedure. For more information on remote user-defined functions, see OpenEdge Application Server: Developing AppServer Applications .

The FUNCTION statement with the IN option must include the following information on the function: the data type it returns, and the data type and mode (INPUT, OUTPUT, or INPUT-OUTPUT) of each parameter.

[ MAP [ TO ] actual-name ] IN proc-handle

Indicates three things: that function-name (the second element in the FUNCTION statement) is an alias (alternative name) of the function, that actual-name is the name that appears in the definition of the function, and that the definition of the function resides in another procedure. actual-name represents the actual name of the function. proc-handle represents an expression that evaluates to a handle to the procedure that defines the function.

Note: The MAP option might simplify your code if it references two different user-defined functions that have the same name but that reside in different procedures.

IN SUPER

Indicates that the implementation of the function resides in a super procedure. For more information on super procedures, see OpenEdge Development: Progress 4GL Handbook .

operationName

The name of a Web service operation specified in a WSDL file.

hPortType

A handle to a procedure object that encapsulates a Web service operation.

Examples

The first example, r-udf1.p, defines and references the user-defined function doubler(), which accepts an integer and returns the integer multiplied by two.

r-udf1.p
/* r-udf1.p */
/* Defines and references a user-defined function */

/* Define doubler() */
FUNCTION doubler RETURNS INTEGER (INPUT parm1 AS INTEGER).
    RETURN (2 * parm1). 
    END FUNCTION.   
    
/* Reference doubler() */
DISPLAY  "doubler(0)=" doubler(0) skip
  "doubler(1)=" doubler(1) skip
  "doubler(2)=" doubler(2) skip. 

The second example, r-udf2.p, forward declares, references, and defines doubler().

r-udf2.p
/* r-udf2.p */
/* Forward-declares, references, and defines a user-defined function */

/* Forward declare doubler() */
FUNCTION doubler RETURNS INTEGER (INPUT parm1 AS INTEGER) FORWARD.    
    
/* Reference doubler() */
DISPLAY "doubler(0)=" doubler(0).
DISPLAY "doubler(1)=" doubler(1).
DISPLAY "doubler(2)=" doubler(2).

/* Define doubler() */
FUNCTION doubler RETURNS INTEGER. 
    RETURN (2 * parm1). 
    END FUNCTION. 

The third example consists of two procedures, r-udf3.p and r-udfdef.p. The example illustrates defining a user-defined function in an external procedure.

The first procedure, r-udf3.p, runs the first procedure persistently, declares doubler(), references it, and deletes the persistent procedure.

r-udf3.p
/* r-udf3.p */
/* references an externally-defined user-defined function */

/* define items */
DEFINE VARIABLE myhand AS HANDLE.
DEFINE VARIABLE mystr  AS CHARACTER FORMAT "x(20)".

/* forward declare doubler() */
FUNCTION doubler RETURNS INTEGER (INPUT parm1 AS INTEGER) IN myhand. 

/* run the procedure that defines doubler() */
RUN src\prodoc\langref\r-udfdef.p PERSISTENT SET myhand. 
    
/* reference doubler() */
DISPLAY  "doubler(0)=" doubler(0) skip
        "doubler(1)=" doubler(1) skip
        "doubler(17)=" doubler(17) skip.

/* delete the procedure that defines doubler */
DELETE PROCEDURE(myhand).  

The second procedure, r-udfdef.p, defines doubler().

r-udfdef.p
/* r-udfdef.p */
/* Defines user-defined function doubler() */

FUNCTION doubler RETURNS INTEGER (INPUT parm1 AS INTEGER).
  RETURN (2 * parm1). 
  END FUNCTION.        

To start the third example, run r-udf3.p in the Procedure Editor.

In the fourth example, r-fctrl2.p, the user-defined function fact() implements the factorial function, common in probability and statistics, and commonly notated “!(6! = 6 x 5 x 4 x 3 x 2; 100! = 100 x 99 x 98 x ... x 2).

r-fctrl2.p
/* r-fctrl2.p */
/* demonstrates user-defined function fact() */

FUNCTION fact RETURNS INTEGER (val AS INTEGER):
  IF val LT 0 THEN RETURN 0.
  IF val LE 1 THEN RETURN 1.
  RETURN val * fact(val - 1).
END.

DEFINE VARIABLE inp AS INTEGER LABEL "Input Value".
REPEAT:
  UPDATE inp WITH TITLE "Factorials".
  DISPLAY fact(inp) LABEL "Factorial".
END. 

Notes

See also

COMPILE statement, DYNAMIC-FUNCTION function, GET-SIGNATURE( ) method, INTERNAL-ENTRIES attribute, Parameter definition syntax, PROGRAM-NAME function, RETURN statement


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095